package com.java.basis.thread.cas.atomic;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * ABA问题解决，可以使用 AtomicStampedReference,可以添加版本号
 * 使用 AtomicStampedReference，可以记录被更改了多少次，但是如果我们并不关心它修改了多少次，只要知道
 * 数据是否被修改，那么有没有更简便的？详看TestABA04
 *
 * @author wangning
 * @create 2022-01-28 15:51
 */
@Slf4j(topic = "c.Test03")
public class TestABA03 {
	static AtomicStampedReference<String> ref = new AtomicStampedReference<>("A", 0);
	public static void main(String[] args) throws InterruptedException {
		//获取版本号
		int stamp = ref.getStamp();
		//获取值
		String prev = ref.getReference();
		other();
		Thread.sleep(1000);

		log.debug("change A->C {}", ref.compareAndSet(prev, "C", stamp, stamp + 1));
		System.out.println(ref.getReference());
	}

	private static void other() throws InterruptedException {
		new Thread(() -> {
			String prev = ref.getReference();
			int stamp = ref.getStamp();
			log.debug("change A->B {}", ref.compareAndSet(prev, "B", stamp, stamp + 1));

		},"t1").start();
		Thread.sleep(500);

		new Thread(() -> {
			String prev = ref.getReference();
			int stamp = ref.getStamp();
			log.debug("change B->A {}", ref.compareAndSet(prev, "A", stamp, stamp + 1));

		}, "t2").start();
	}
}
